<template>
  <div class="app-container">
    <!-- 页面标题 -->
    <div class="page-header">
      <h3 class="page-title">ADE Prompt Exploration</h3>
      <p class="page-description">
        Analyze medical progress notes using different prompt templates and
        compare the response results of Large Language Models (LLMs)
      </p>
    </div>
    <el-form :model="form" ref="queryForm" size="mini">
      <el-card class="form-card" style="padding: 0px">
        <!-- 第一部分：需要输入的待分析的病程记录内容 -->
        <el-form-item label="Content" prop="content">
          <el-input v-model="form.content" type="textarea" :rows="6" placeholder="Pls input medical notes..." clearable
            class="content-input" />
        </el-form-item>

        <!-- 第二部分：选择用于分析病程记录的大模型 -->
        <el-form-item label="Select LLm" prop="llm">
          <el-select v-model="form.llm" placeholder="Select LLM Model" clearable class="model-select">
            <el-option v-for="dict in dict.type.llm_model" :key="dict.value" :label="dict.label" :value="dict.value" />
          </el-select>
          &nbsp;&nbsp;&nbsp;
          <el-button type="primary" icon="el-icon-search" @click="analyzePrompts" :loading="loading">
            Analyze
          </el-button>
        </el-form-item>
      </el-card>

      <!-- 第三部分： 选择Prompt Template， 显示Prompt内容，展示分析结果 -->
      <el-row :gutter="10" class="prompt-container">
        <!-- 第一个Prompt Template 及分析结果 -->
        <el-col :span="8">
          <el-card class="prompt-card" shadow="hover">
            <div slot="header" class="clearfix">
              <span style="font-size: 14px; font-style: bold; font-weight: 600">Prompt One</span>
            </div>

            <!-- 选择Prompt Template One -->
            <el-form-item>
              <el-select v-model="form.promptOne" placeholder="Select Prompt" clearable
                @change="(value) => handleChange(value, 'one')" class="prompt-select">
                <el-option v-for="dict in prompts" :key="dict.id" :label="dict.identifier" :value="dict.id" />
              </el-select>
            </el-form-item>

            <el-row :gutter="1" v-if="ragOne">
              <el-col :span="6">
                <!--选择 ADE 库-->
                <el-form-item prop="adekbidOne">
                  <el-select v-model="form.adekbidOne" placeholder="Select ADE KB" size="mini" clearable>
                    <el-option v-for="dict in adekbs" :key="dict.id" :label="dict.name" :value="dict.id" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <!--选择切分方式-->
                <el-form-item prop="chunkTypeOne">
                  <el-select v-model="form.chunkTypeOne" placeholder="Select Chunk Type" size="mini" clearable>
                    <el-option v-for="dict in dict.type.chunk_type" :key="dict.value" :label="dict.label"
                      :value="dict.value" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <!--选择相似度阀值-->
                <el-form-item prop="simScoreThresholdOne">
                  <el-input-number v-model="form.simScoreThresholdOne" placeholder="Similarity Score" />
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <!--选择topN-->
                <el-form-item prop="topNOne">
                  <el-input-number v-model="form.topNOne" placeholder="Top N" :min="1" :max="100" />
                </el-form-item>
              </el-col>
            </el-row>


            <!-- 显示Prompt Template One 对应的内容 -->
            <el-form-item>
              <pre class="prompt-content">{{ form.promptOneContent }} </pre>
            </el-form-item>

            <!-- 展示Prompt Template One 对应的分析结果 -->
            <el-form-item>
              <div style="text-align: left; font-weight: 600;font-size: 12px; ">
                <span>ADE Identification Result</span>
              </div>
              <el-card class="result-card" style="margin-bottom: 10px;">

                <pre v-if="result.promptOneResult" class="result-json">{{
                  formatJson(result.promptOneResult)
                }}</pre>
                <div v-else class="no-result">
                  <i class="el-icon-info"></i> No results yet, please select a
                  prompt and submit for analysis
                </div>
              </el-card>

              <div style="text-align: left; font-weight: 600;font-size: 12px; ">
                <span>Referenced ADE Knowledges</span>
              </div>
              <el-card class="result-card">
                <pre v-if="knowledge.promptOneResult" class="result-json">{{
                  formatJson(knowledge.promptOneResult)
                }}</pre>
                <div v-else class="no-result">
                  <i class="el-icon-info"></i> No Knowledge results!
                </div>
              </el-card>
            </el-form-item>
          </el-card>
        </el-col>

        <!-- 第二个Prompt Template 及分析结果 -->
        <el-col :span="8">
          <el-card class="prompt-card" shadow="hover">
            <div slot="header" class="clearfix">
              <span style="font-size: 14px; font-style: bold; font-weight: 600">Prompt Two</span>
            </div>

            <!-- 选择Prompt Template Two -->

            <el-form-item>
              <el-select v-model="form.promptTwo" placeholder="Select Prompt" clearable
                @change="(value) => handleChange(value, 'two')" class="prompt-select">
                <el-option v-for="dict in prompts" :key="dict.id" :label="dict.identifier" :value="dict.id" />
              </el-select>
            </el-form-item>

            <!--RAG Two配置-->
            <el-row :gutter="1" v-if="ragTwo">
              <el-col :span="6">
                <!--选择 ADE 库-->
                <el-form-item prop="adekbidTwo">
                  <el-select v-model="form.adekbidTwo" placeholder="Select ADE KB" size="mini" clearable>
                    <el-option v-for="dict in adekbs" :key="dict.id" :label="dict.name" :value="dict.id" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <!--选择切分方式-->
                <el-form-item prop="chunkTypeTwo">
                  <el-select v-model="form.chunkTypeTwo" placeholder="Select Chunk Type" size="mini" clearable>
                    <el-option v-for="dict in dict.type.chunk_type" :key="dict.value" :label="dict.label"
                      :value="dict.value" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <!--选择相似度阀值-->
                <el-form-item prop="simScoreThresholdTwo">
                  <el-input-number v-model="form.simScoreThresholdTwo" placeholder="Similarity Score" />
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <!--选择topN-->
                <el-form-item prop="topNTwo">
                  <el-input-number v-model="form.topNTwo" placeholder="Top N" :min="1" :max="100" />
                </el-form-item>
              </el-col>
            </el-row>

            <!-- 显示Prompt Template Two 对应的内容 -->
            <el-form-item>
              <pre class="prompt-content">{{ form.promptTwoContent }} </pre>
            </el-form-item>

            <!-- 展示Prompt Template Two 对应的分析结果 -->

            <el-form-item>
              <div style="text-align: left; font-weight: 600;font-size: 12px; ">
                <span>ADE Identification Result</span>
              </div>
              <el-card class="result-card">
                <pre v-if="result.promptTwoResult" class="result-json">{{
                  formatJson(result.promptTwoResult)
                }}</pre>
                <div v-else class="no-result">
                  <i class="el-icon-info"></i> No results yet, please select a
                  prompt and submit for analysis
                </div>
              </el-card>

              <div style="text-align: left; font-weight: 600;font-size: 12px; ">
                <span>Referenced ADE Knowledges</span>
              </div>
              <el-card class="result-card">
                <pre v-if="knowledge.promptTwoResult" class="result-json">{{
                  formatJson(knowledge.promptTwoResult)
                }}</pre>
                <div v-else class="no-result">
                  <i class="el-icon-info"></i> No Knowledge results!
                </div>
              </el-card>
            </el-form-item>
          </el-card>
        </el-col>

        <!-- 第三个Prompt Template 及分析结果 -->
        <el-col :span="8">
          <el-card class="prompt-card" shadow="hover">
            <div slot="header" class="clearfix">
              <span style="font-size: 14px; font-style: bold; font-weight: 600">Prompt Three</span>
            </div>

            <!-- 选择Prompt Template Three -->

            <el-form-item>
              <el-select v-model="form.promptThree" placeholder="Select Prompt" clearable
                @change="(value) => handleChange(value, 'three')" class="prompt-select">
                <el-option v-for="dict in prompts" :key="dict.id" :label="dict.identifier" :value="dict.id" />
              </el-select>
            </el-form-item>

            <!--RAG Three配置-->
            <el-row :gutter="1" v-if="ragThree">
              <el-col :span="6">
                <!--选择 ADE 库-->
                <el-form-item prop="adekbidThree">
                  <el-select v-model="form.adekbidThree" placeholder="Select ADE KB" size="mini" clearable>
                    <el-option v-for="dict in adekbs" :key="dict.id" :label="dict.name" :value="dict.id" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <!--选择切分方式-->
                <el-form-item prop="chunkTypeThree">
                  <el-select v-model="form.chunkTypeThree" placeholder="Select Chunk Type" size="mini" clearable>
                    <el-option v-for="dict in dict.type.chunk_type" :key="dict.value" :label="dict.label"
                      :value="dict.value" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <!--选择相似度阀值-->
                <el-form-item prop="simScoreThresholdThree">
                  <el-input-number v-model="form.simScoreThresholdThree" placeholder="Similarity Score" />
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <!--选择topN-->
                <el-form-item prop="topNThree">
                  <el-input-number v-model="form.topNThree" placeholder="Top N" :min="1" :max="100" />
                </el-form-item>
              </el-col>
            </el-row>

            <!-- 显示Prompt Template Three 对应的内容 -->
            <el-form-item>
              <pre class="prompt-content">{{ form.promptThreeContent }} </pre>
            </el-form-item>

            <!-- 展示Prompt Template Three 对应的分析结果 -->
            <el-form-item>
              <div style="text-align: left; font-weight: 600;font-size: 12px; ">
                <span>ADE Identification Result</span>
              </div>
              <el-card class="result-card">
                <pre v-if="result.promptThreeResult" class="result-json">{{
                  formatJson(result.promptThreeResult)
                }}</pre>
                <div v-else class="no-result">
                  <i class="el-icon-info"></i> No results yet, please select a
                  prompt and submit for analysis
                </div>
              </el-card>

              <div style="text-align: left; font-weight: 600;font-size: 12px; ">
                <span>Referenced ADE Knowledges</span>
              </div>
              <el-card class="result-card">
                <pre v-if="knowledge.promptThreeResult" class="result-json">{{
                  formatJson(knowledge.promptThreeResult)
                }}</pre>
                <div v-else class="no-result">
                  <i class="el-icon-info"></i> No Knowledge results!
                </div>
              </el-card>
            </el-form-item>
          </el-card>
        </el-col>
      </el-row>

    </el-form>
  </div>
</template>

<script>
import { listAllPrompt } from "@/api/ade/prompt";
import { recognizeByPrompt } from "@/api/ade/adeRecognition";
import { listAllAdebase } from "@/api/ade/adebase";

export default {
  name: "PromptExplorer",
  dicts: ["llm_model", "yes_or_no", "chunk_type"],
  data() {
    return {
      //
      adekbs: [], // ADE知识库列表
      // 遮罩层
      loading: false,
      prompts: [],
      // 表单参数
      form: {
        content: "",
        llm: null,
        promptOne: null,
        promptOneContent: null,
        promptTwo: null,
        promptTwoContent: null,
        promptThree: null,
        promptThreeContent: null,

        adekbidOne: null, // 第一个ADE知识库ID
        adekbidTwo: null, // 第二个ADE知识库ID
        adekbidThree: null, // 第三个ADE知识库ID
        chunkTypeOne: "mark", // 第一个RAG切分方式
        chunkTypeTwo: "mark", // 第二个RAG切分方式
        chunkTypeThree: "mark", // 第三个RAG切分方式
        simScoreThresholdOne: 0.7, // 第一个RAG相似度阈值
        simScoreThresholdTwo: 0.7, // 第二个RAG相似度阈值
        simScoreThresholdThree: 0.7, // 第三个RAG相似度阈值
        topNOne: 5, // 第一个RAG返回结果数量
        topNTwo: 5, // 第二个RAG返回结果数量
        topNThree: 5, // 第三个RAG返回结果数量
      },
      ragOne: false,
      ragTwo: false,
      ragThree: false,
      result: {
        promptOneResult: null,
        promptTwoResult: null,
        promptThreeResult: null,
      },
      knowledge: {
        promptOneResult: null,
        promptTwoResult: null,
        promptThreeResult: null,
      },
      // 错误信息
      errors: {
        content: false,
        llm: false,
        prompts: false,
      },
    };
  },
  created() {
    // 页面加载时获取所有Prompt
    this.getPrompts();
    this.listallAdebases(); // 获取所有ADE知识库
  },
  methods: {
    //获取所有的ADE知识库
    listallAdebases() {
      var data = { status: '' };
      // Fetch all ADE knowledge bases
      listAllAdebase(data).then(response => {
        this.adekbs = response.data;
        if (this.adekbs.length > 0) {
          this.form.adekbidOne = this.adekbs[0].id; // 默认选择第一个ADE知识库
          this.form.adekbidTwo = this.adekbs[0].id; // 默认选择第一个ADE知识库
          this.form.adekbidThree = this.adekbs[0].id; // 默认选择第一个ADE知识库
        }
      }).catch(error => {
        this.$message.error("Failed to load ADE knowledge bases: " + error.message);
      });
    },
    // 获取所有的Prompt Template
    getPrompts() {
      this.loading = true;
      var data = {};
      listAllPrompt(data)
        .then((response) => {
          this.prompts = response.data;
          console.log("Prompts fetched successfully:", this.prompts);
        })
        .catch((error) => {
          console.error("Error fetching prompts:", error);
          this.$message.error("获取Prompt模板失败，请重试");
        })
        .finally(() => {
          this.loading = false;
        });
    },

    // 处理Prompt选择变化
    handleChange(value, para) {
      console.log("Selected Prompt ID:", value, "Parameter:", para);
      // 根据选择的Prompt ID获取对应的内容
      const selectedPrompt = this.prompts.find((prompt) => prompt.id === value);
      if (selectedPrompt) {
        if (para === "one") {
          this.form.promptOneContent =
            selectedPrompt.systemPrompt + "\n" + selectedPrompt.userPrompt;
          if (selectedPrompt.type === "RAG") {
            this.ragOne = true;
          } else {
            this.ragOne = false;
          }
        } else if (para === "two") {
          this.form.promptTwoContent =
            selectedPrompt.systemPrompt + "\n" + selectedPrompt.userPrompt;
          if (selectedPrompt.type === "RAG") {
            this.ragTwo = true;
          } else {
            this.ragTwo = false;
          }
        } else if (para === "three") {
          this.form.promptThreeContent =
            selectedPrompt.systemPrompt + "\n" + selectedPrompt.userPrompt;
          if (selectedPrompt.type === "RAG") {
            this.ragThree = true;
          } else {
            this.ragThree = false;
          }
        }
      } else {
        if (para === "one") {
          this.form.promptOne = null;
          this.form.promptOneContent = null;
          this.result.promptOneResult = null;
          this.knowledge.promptOneResult = null;
          this.ragOne = false; // 重置RAG状态
        } else if (para === "two") {
          this.form.promptTwo = null;
          this.form.promptTwoContent = null;
          this.result.promptTwoResult = null;
          this.knowledge.promptTwoResult = null;
          this.ragTwo = false; // 重置RAG状态
        } else if (para === "three") {
          this.form.promptThree = null;
          this.form.promptThreeContent = null;
          this.result.promptThreeResult = null;
          this.knowledge.promptThreeResult = null;
          this.ragThree = false; // 重置RAG状态
        }

      }
    },

    // 格式化JSON结果
    formatJson(jsonData) {
      try {
        if (typeof jsonData === "string") {
          return JSON.stringify(JSON.parse(jsonData), null, 2);
        }
        return JSON.stringify(jsonData, null, 2);
      } catch (error) {
        console.error("Failed to format JSON:", error);
        return jsonData;
      }
    },

    // 分析所有选中的Prompt
    analyzePrompts() {
      // 表单验证
      if (!this.form.content) {
        this.errors.content = true;
        this.$message.warning("Pls input medical notes!");
        return;
      }

      if (!this.form.llm) {
        this.errors.llm = true;
        this.$message.warning("Pls select a Large Language Model!");
        return;
      }

      const selectedPrompts = [
        this.form.promptOne,
        this.form.promptTwo,
        this.form.promptThree,
      ].filter(Boolean);

      console.log("Selected Prompts:", selectedPrompts);

      if (selectedPrompts.length === 0) {
        this.errors.prompts = true;
        this.$message.warning("Pls select at least one Prompt Template!");
        return;
      }

      // 重置错误标志
      this.errors = {
        content: false,
        llm: false,
        prompts: false,
      };


      // 构建请求数据
      var analysisRequests = [];
      if (this.form.promptOne != null) {
        if (this.ragOne) {
          if (this.form.adekbidOne == null) {
            this.$message.warning("Pls select ADE knowledge base for Prompt One!");
            return;
          }
          if (this.form.chunkTypeOne == null) {
            this.$message.warning("Pls select chunk type for Prompt One!");
            return;
          }
          if (this.form.simScoreThresholdOne == null) {
            this.$message.warning("Pls input similarity score threshold for Prompt One!");
            return;
          }
          if (this.form.topNOne == null) {
            this.$message.warning("Pls input top N for Prompt One!");
            return;
          }
        }
        // 如果选择了第一个Prompt，使用第一个RAG的配置
        analysisRequests.push({
          flag: "one",
          emr: this.form.content,
          llmModel: this.form.llm,
          promptId: this.form.promptOne,
          simScoreThreshold: this.form.simScoreThresholdOne, // 使用第一个RAG的相似度阈值
          topN: this.form.topNOne, // 使用第一个RAG的返回结果数量
          adekbid: this.form.adekbidOne, // 使用第一个ADE知识库ID
          chunkType: this.form.chunkTypeOne, // 使用第一个RAG的切分方式
        });
      }

      if (this.form.promptTwo != null) {
        if (this.ragTwo) {
          if (this.form.adekbidTwo == null) {
            this.$message.warning("Pls select ADE knowledge base for Prompt Two!");
            return;
          }
          if (this.form.chunkTypeTwo == null) {
            this.$message.warning("Pls select chunk type for Prompt Two!");
            return;
          }
          if (this.form.simScoreThresholdTwo == null) {
            this.$message.warning("Pls input similarity score threshold for Prompt Two!");
            return;
          }
          if (this.form.topNTwo == null) {
            this.$message.warning("Pls input top N for Prompt Two!");
            return;
          }
        }
        // 如果选择了第二个Prompt，使用第二个RAG的配置
        analysisRequests.push({
          flag: "two",
          emr: this.form.content,
          llmModel: this.form.llm,
          promptId: this.form.promptTwo,
          simScoreThreshold: this.form.simScoreThresholdTwo, // 使用第二个RAG的相似度阈值
          topN: this.form.topNTwo, // 使用第二个RAG的返回结果数量
          adekbid: this.form.adekbidTwo, // 使用第二个ADE知识库ID
          chunkType: this.form.chunkTypeTwo, // 使用第二个RAG的切分方式
        });
      }

      if (this.form.promptThree != null) {
        if (this.ragThree) {
          if (this.form.adekbidThree == null) {
            this.$message.warning("Pls select ADE knowledge base for Prompt Three!");
            return;
          }
          if (this.form.chunkTypeThree == null) {
            this.$message.warning("Pls select chunk type for Prompt Three!");
            return;
          }
          if (this.form.simScoreThresholdThree == null) {
            this.$message.warning("Pls input similarity score threshold for Prompt Three!");
            return;
          }
          if (this.form.topNThree == null) {
            this.$message.warning("Pls input top N for Prompt Three!");
            return;
          }
        }
        // 如果选择了第三个Prompt，使用第三个RAG的配置
        analysisRequests.push({
          flag: "three",
          emr: this.form.content,
          llmModel: this.form.llm,
          promptId: this.form.promptThree,
          simScoreThreshold: this.form.simScoreThresholdThree, // 使用第三个RAG的相似度阈值
          topN: this.form.topNThree, // 使用第三个RAG的返回结果数量
          adekbid: this.form.adekbidThree, // 使用第三个ADE知识库ID
          chunkType: this.form.chunkTypeThree, // 使用第三个RAG的切分方式
        });
      }

      this.loading = true;
      console.log("Analysis Requests:", analysisRequests);

      // 并行发送分析请求
      const promises = analysisRequests.map((request) => {
        return recognizeByPrompt(request).then((response) => {
          // 确定结果对应的Prompt
          let resultKey;
          if (request.flag === 'one') {
            resultKey = "promptOneResult";
          } else if (request.flag === 'two') {
            resultKey = "promptTwoResult";
          } else if (request.flag === 'trhee') {
            resultKey = "promptThreeResult";
          }

          if (resultKey) {
            this.result[resultKey] = response.data.ades;
            this.knowledge[resultKey] = response.data.references;
          }

          return response;
        });
      });

      // 等待所有请求完成
      Promise.allSettled(promises)
        .then((results) => {
          const successCount = results.filter(
            (r) => r.status === "fulfilled"
          ).length;
          const errorCount = results.length - successCount;

          if (errorCount > 0) {
            this.$message.warning(
              `部分分析请求失败，成功 ${successCount} 个，失败 ${errorCount} 个`
            );
          } else {
            this.$message.success("分析完成");
          }
        })
        .catch((error) => {
          console.error("Error analyzing prompts:", error);
          this.$message.error("分析过程中发生错误，请重试");
        })
        .finally(() => {
          this.loading = false;
        });
    },

    // 重置表单
    resetForm() {
      this.$refs.queryForm.resetFields();
      this.result = {
        promptOneResult: null,
        promptTwoResult: null,
        promptThreeResult: null,
      };
    },
  },
};
</script>

<style scoped>
.page-header {
  margin-bottom: 20px;
}

.page-title {
  margin-top: 5px;
  font-size: 22px;
  color: #303133;
  margin-bottom: 0px;
  font-weight: bold;
}

.page-description {
  font-size: 16px;
  color: #606266;
  line-height: 1.5;
}

.form-card {
  margin-bottom: 10px;
  padding: 0px;
}

.content-input {
  width: 100%;
}

.model-select {
  width: 200px;
}

.prompt-container {
  margin-bottom: 20px;
}

.prompt-card {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.prompt-select {
  width: 100%;
}

.prompt-content {
  background-color: #f5f5f5;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 5px;
  font-family: 'Courier New', Courier, monospace;
  font-size: 12px;
  line-height: 1.5;
  overflow-x: auto;
  white-space: pre-wrap;
  color: #333;
}

.result-card {
  background-color: #f5f7fa;
  min-height: 90px;
  overflow-y: auto;
  padding: 10px;
}

.result-json {
  font-family: Consolas, Monaco, "Andale Mono", monospace;
  font-size: 13px;
  line-height: 18px;
  white-space: pre-wrap;
  word-break: break-all;
  margin: 0;
}

.no-result {
  color: #909399;
  text-align: center;
  padding: 20px 0;
}

.action-buttons {
  text-align: center;
  margin-top: 20px;
}

.el-form-item {
  margin-bottom: 10px;
}
</style>